package me.chinaq.fastweb;

import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PropertiesLoaderUtils;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.nio.file.*;
import java.util.Properties;

/**
 * 项目常量。
 * 配置文件里的变量用static修饰，类里固定的变量用final修饰
 */
public class ProjectConstant {
	static {
		loadFile();
		watchFile();
	}

	static final String FAST_CONFIG = "fast.properties";
	public static final String BASE_PACKAGE = "me.chinaq.fastweb";//项目基础包名称，根据自己公司的项目修改

	public static final String MODEL_PACKAGE = BASE_PACKAGE + ".bean";//Model所在包
	public static final String MAPPER_PACKAGE = BASE_PACKAGE + ".dao";//Mapper所在包
	public static final String SERVICE_PACKAGE = BASE_PACKAGE + ".service";//Service所在包
	public static final String SERVICE_IMPL_PACKAGE = SERVICE_PACKAGE + ".impl";//ServiceImpl所在包
	public static final String CONTROLLER_PACKAGE = BASE_PACKAGE + ".web";//Controller所在包

	public static final String MAPPER_INTERFACE_REFERENCE = BASE_PACKAGE + ".dao.BaseDao";//Mapper插件基础接口的完全限定名

	public static int C;
	public static String D;
	public static String b;

	private static void loadFile() {
		ClassPathResource resource = new ClassPathResource(FAST_CONFIG);
		try {
			reload(resource);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static void watchFile() {
		new Thread(() -> {
			WatchService watchService = null;
			ClassPathResource resource = new ClassPathResource(FAST_CONFIG);
			try {
				watchService = FileSystems.getDefault().newWatchService();
				Path path = Paths.get(resource.getFile().getParent());
				path.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY);
			} catch (IOException e) {
				e.printStackTrace();
			}
			while (true) {
				WatchKey wk = null;
				try {
					wk = watchService.take();
				} catch (Exception e) {
					e.printStackTrace();
					continue;
				}
				for (WatchEvent<?> event : wk.pollEvents()) {
					Path path = (Path) event.context();
					String pathStr = path.toString();
					if (FAST_CONFIG.equals(pathStr)) {
						try {
//							reloadConstant(new ClassPathResource(pathStr));
							reload(resource);
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
				}
				wk.reset();
			}
		}).start();
	}

	private static void reload(ClassPathResource resource) throws IOException, InvocationTargetException, IllegalAccessException, NoSuchFieldException {
		Properties properties = PropertiesLoaderUtils.loadProperties(resource);
		for (Object key : properties.keySet()) {
			String filedName = key.toString();
			Field field = ProjectConstant.class.getDeclaredField(filedName);
			if (field == null) {
				System.out.println(filedName + "变量在类中不存在");
				continue;
			}
			//field.getModifiers() == 9表示为public static变量
			String typeName = field.getType().getName();
			if (typeName.equals(String.class.getName())) {
				field.set(null, properties.get(key));
			} else if (typeName.equals("int")) {
				field.set(null, Integer.valueOf(properties.get(key).toString()));
			} else {
				field.set(null, properties.get(key));
			}
		}
	}

	public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
		Field field = ProjectConstant.class.getDeclaredField("C");
		field.setInt(null, 100);
		System.out.println(C);
		Field fieldB = ProjectConstant.class.getDeclaredField("b");
		fieldB.set(null, "bbbbbbbbbb");
		System.out.println(b);
	}

}
